package util.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import model.dao.AlunoDAO;

public final class DAOFactory {

	private static final String PROPERTY_URL = "url";
	private static final String PROPERTY_DRIVER = "driver";
	private static final String PROPERTY_USERNAME = "username";
	private static final String PROPERTY_PASSWORD = "password";
	private static final Map<String, DAOFactory> INSTANCES = new HashMap<String, DAOFactory>();

	private static String url;
	private static String username;
	private static String password;
	private static DataSource dataSource;

	private DAOFactory(String name) throws DAOConfigurationException {
		DAOProperties properties = new DAOProperties(name);
		this.url = properties.getProperty(PROPERTY_URL, true);
		String driverClassName = properties.getProperty(PROPERTY_DRIVER, false);
		this.password = properties.getProperty(PROPERTY_PASSWORD, false);
		this.username = properties.getProperty(PROPERTY_USERNAME, this.password != null);

		if (driverClassName != null) {
			// If driver is specified, then load it and let it register itself with DriverManager.
			try {
				Class.forName(driverClassName);
			} catch (ClassNotFoundException e) {
				throw new DAOConfigurationException(
						"Classe driver '" + driverClassName + "' não encontrada no classpath.", e);
			}
		} else {
			// Else assume URL as DataSource URL and lookup it in the JNDI.
			try {
				dataSource = (DataSource) new InitialContext().lookup(url);
			} catch (NamingException e) {
				throw new DAOConfigurationException(
						"DataSource '" + url + "' não encontrada no JNDI.", e);
			}
		}
	}

	public static DAOFactory getInstance(String name) throws DAOConfigurationException {
		if (name == null) {
			throw new DAOConfigurationException("Nome da base de dados é nulo.");
		}
		DAOFactory instance = INSTANCES.get(name);
		if (instance == null) {
			instance = new DAOFactory(name);
			INSTANCES.put(name, instance);
		}
		return instance;
	}

	public static Connection getConnection() throws SQLException {
		if (dataSource != null) {
			if (username != null) {
				return dataSource.getConnection(username, password);
			} else {
				return dataSource.getConnection();
			}
		} else {
			return DriverManager.getConnection(url, username, password);
		}
	}
}
